Creating Windows
The Venn Diagrammer application allows the user to have multiple document windows (that is, multiple Venn diagram windows) on the desktop at the same time. Each different document window probably displays a different syllogism. As a result, the application needs some way to keep track of each window's current settings.A standard way to do this is to make use of the
refCon
field in the window record. TherefCon
field is reserved specifically for use by applications, which can set the field (using theSetWRefCon
procedure) to any 4-byte value. Often, applications store a handle to an application-defined data structure that describes the window. This data structure is often known as a document record. Given the window pointer, you can retrieve that handle by calling theGetWRefCon
function.The sample code in this book uses a document record of type
MyDocRec
(shown in Listing 6-5) to store information about the current contents of a Venn diagram window.Listing 6-5 The structure of a document record for the Venn Diagrammer application
TYPE MyDocRec = {information for a document window} RECORD figure: Integer; {the figure of the syllogism} mood: ARRAY[1..3] OF Integer; {the moods of the statements} terms: ARRAY[1..3] OF Str31; {the three terms} statusText: Str255; {most recent status message} userSolution: MyDiagramState; {user's diagram state} realSolution: MyDiagramState; {answer's diagram state} isAnswerShowing: Boolean; {is the answer showing?} isExistImport: Boolean; {stmts imply exists subject?} needsAdjusting: Boolean; {diagram needs adjusting?} END; MyDocRecPtr = ^MyDocRec; MyDocRecHnd = ^MyDocRecPtr;As you can see, the document record used by the Venn Diagrammer application contains fields that describe the current settings of the syllogism in the window, including the figure of the syllogism, the mood of each statement in the syllogism, and the terms used in those statements. The document record also contains fields that maintain information about the current appearance of the window, such as the status message most recently displayed in the window's status area (statusText
field) and a Boolean value that indicates whether the answer is visible in the window (isAnswerShowing
field). The Venn Diagrammer application uses that Boolean value to determine how to fill in the regions in the overlapping circles. If the value ofisAnswerShowing
isTRUE
, the application displays the correct answer (encoded in therealSolution
field); otherwise, the application displays the user's current answer (encoded in theuserSolution
field).
The
- Note
- The structure of the
MyDiagramState
data type is not shown in this book.![]()
MyDocRec
data structure also contains two other fields containing Boolean values. These specify whether the statements that make up the syllogism are to be interpreted as having existential import or not, and whether the window needs to be checked for automatic adjustment.
The Venn Diagrammer application creates a document record every time it creates a document window, and it stores a handle to the document record in the
- IMPORTANT
- If a Venn diagram window contained TextEdit fields or controls (such as radio buttons or scroll bars), the document record could be expanded to include handles to those items. Also, if a file were associated with the window, you'd want the document record to include information about that file. In a nutshell, the document record can contain all relevant information about the window that isn't contained in the window record.
![]()
refCon
field of the window record. Listing 6-6 shows theDoCreateWindow
routine, which creates a new document window. This function is called when the application is first launched and whenever the user chooses the New command from the File menu.Listing 6-6 Creating a new Venn diagram window
FUNCTION DoCreateWindow: WindowPtr; VAR myPointer: Ptr; myWindow: WindowPtr; myHandle: MyDocRecHnd; BEGIN myPointer := NewPtr(sizeof(WindowRecord)); IF myPointer = NIL THEN exit(DoCreateWindow); myWindow := GetNewWindow(rVennD, myPointer, WindowPtr(-1)); IF myWindow <> NIL THEN BEGIN SetPort(myWindow); myHandle := MyDocRecHnd(NewHandleClear(sizeof(MyDocRec))); IF myHandle <> NIL THEN BEGIN HLockHi(Handle(myHandle)); {lock the data high in the heap} SetWRefCon(myWindow, LongInt(myHandle)); {attach handle to window record} DoSetWindowTitle(myWindow); {set the window title} {Define initial window settings.} WITH myHandle^^ DO BEGIN figure := 1; mood[1] := 1; mood[2] := 1; mood[3] := 1; isAnswerShowing := FALSE; isExistImport := gGiveImport; END; DoGetRandomTerms(myWindow); DoCalcAnswer(myWindow); {Position the window and display it.} DoPositionWindow(myWindow); ShowWindow(myWindow); END {IF myHandle <> NIL} ELSE BEGIN {couldn't get a data record} CloseWindow(myWindow); DisposePtr(Ptr(myWindow)); myWindow := NIL; {so pass back NIL} END; END; DoCreateWindow := myWindow; END;TheDoCreateWindow
function first attempts to allocate space in the heap for a window record by calling the Memory Manager'sNewPtr
function. If no space is available,DoCreateWindow
exits and returnsNIL
to indicate that no new window was created. Otherwise,DoCreateWindow
creates the new window, whose size and type are defined in a window resource of typerVennD
.
CONST rVennD = 131; {resource ID of document window}If the new window is successfully created,DoCreateWindow
next tries to allocate space for a document record. Once again, if the space isn't available,DoCreateWindow
takes care to dispose of the new window and returnNIL
to the calling routine. Otherwise,DoCreateWindow
locks the handle to the document record high in the heap and attaches the document record to the window record by callingSetWRefCon
.
The
- Note
- The document record data is locked at the top of the heap to help prevent heap fragmentation. See the chapter "Introduction to Memory Management" in Inside Macintosh: Memory for a discussion of when you need to lock data in the heap.
![]()
DoCreateWindow
function next sets up the window's title (by calling the application-defined procedureDoSetWindowTitle
) and initializes some of the fields in the document record. ThenDoCreateWindow
calls two further application-defined procedures (DoGetRandomTerms
andDoCalcAnswer
) to initialize theterms
field and therealSolution
field of the document record. (As for theuserSolution
field, theNewHandleClear
function, which sets all bytes in the block to 0, automatically initializes it to encode an empty diagram, according to a clever scheme.)The application-defined procedure
DoPositionWindow
sets the original position of the new window according to the user's expectations and good human interface design. ThenDoCreateWindow
calls the Window Manager procedureShowWindow
to display the window. TheShowWindow
procedure generates and update event for the newly displayed window, thereby causing the Venn Diagrammer application to draw the content region of the window.
- Note
- The procedure
DoPositionWindow
is not defined in this book. For a discussion of how to determine the position of a new window, see the chapter "Window Manager" in Inside Macintosh: Macintosh Toolbox Essentials.![]()